package it.java.giw.solr;

import it.java.giw.jsf.ImgResult;
import it.java.giw.jsf.Result;

import java.io.Serializable;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse.Suggestion;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.params.ModifiableSolrParams;

public class ImgSearcher implements Serializable{
	private String collatedQuery;
	private String originalQuery;
	private static final long serialVersionUID = -4629314027623692321L;

	public ImgResult search(String queryStrings) throws MalformedURLException, SolrServerException {
		this.originalQuery = queryStrings;
		QueryResponse response = null;
		if (queryStrings != null &&  !queryStrings.isEmpty()) { 

			try {
				SolrServer server = new HttpSolrServer("http://localhost:8983/solr");
				ModifiableSolrParams params = new ModifiableSolrParams();
				params.set("qt", "/browse");
				params.set("spellcheck", "true");
				params.set("spellcheck.collate", "true");
				SolrQuery query = new SolrQuery();
				query.setQuery(queryStrings);
				query.add(params);
				
				response = server.query(query);
				response = getSuggestions(queryStrings, server, response);			
			}
			catch(Exception e){
				e.printStackTrace();
			}	
		}	
		return createImgResult(response);
	}


	private ImgResult createImgResult(QueryResponse response) {
		ImgResult r = new ImgResult();
		r.setCollatedQuery(this.collatedQuery);
		r.setOriginalQuery(this.originalQuery);
		List<String> imgUrls = new ArrayList<String>();
		for (SolrDocument d : response.getResults()){
			String responseUrls = d.getFieldValue("img").toString();
			responseUrls = responseUrls.substring(1, responseUrls.length()-1);
			System.out.println(responseUrls);
			String[] imgUrlsInDocument = responseUrls.split(",");
			for(int i = 0;i<imgUrlsInDocument.length; i++){
				String url = imgUrlsInDocument[i];
				System.out.println(url);
				if(parseUrl(url))
					imgUrls.add(url);
			}
		}
		r.setImgUrls(imgUrls);
		return r;
	}
	
	private boolean parseUrl(String url) {
		Pattern pattern = Pattern.compile("http(.)*\\.(jpg|JPG)$");
		Matcher match = pattern.matcher(url);
		boolean matches = match.find();
		return matches;
		
	}


	private QueryResponse getSuggestions(String queryStrings, SolrServer server, QueryResponse response)
			throws SolrServerException {
		boolean found;
		SpellCheckResponse scr = null;
		String collatedString ="";
		if(response != null){
			scr = response.getSpellCheckResponse();
			if(scr != null){
				List<Suggestion> suggLst = scr.getSuggestions();
				queryStrings = queryStrings.toLowerCase();
				StringTokenizer tokenizer = new StringTokenizer(queryStrings);
				while (tokenizer.hasMoreTokens()){
					found = false;
					String token = tokenizer.nextToken();
					if (suggLst.isEmpty())
						collatedString = queryStrings;
					else{
						for (Suggestion sugg : suggLst){
							if (token.equals(sugg.getToken())){
								collatedString = collatedString.concat(sugg.getAlternatives().get(0)+" ");
								found = true;
								break;
							}
						}
						if (!found)
							collatedString = collatedString.concat(token+" ");
					}
				}
			}
		}
		
		/* response ricalcolata sulla stringa collated, con boosting per phrase query */
		SolrQuery queryCollated = new SolrQuery(collatedString+boost(collatedString));
		ModifiableSolrParams params = new ModifiableSolrParams();
		params.set("qt", "/browse");
		params.set("facet", "true");
		queryCollated.setStart(0);
		queryCollated.setRows(500);
		queryCollated.setParam("fl", "img");
		queryCollated.add(params);
		response = server.query(queryCollated);
		/* set collated query */
		this.setCollatedQuery(collatedString);
		return response;
	}

	private void setCollatedQuery(String collatedString) {
		this.collatedQuery = collatedString;
	}

	private String boost(String collated) {
		String boostedPhraseQuery = " OR \""+collated+"\"^150";
		return boostedPhraseQuery;
	}
	
	public ImgResult searchWithoutSuggestions(String queryStrings) throws MalformedURLException, SolrServerException {
		this.originalQuery = queryStrings;
		QueryResponse response = null;
		if (queryStrings != null &&  !queryStrings.isEmpty()) { 

			try {
				SolrServer server = new HttpSolrServer("http://localhost:8983/solr");
				SolrQuery query = new SolrQuery();
				ModifiableSolrParams params = new ModifiableSolrParams();
				params.set("qt", "/browse");				
				params.set("facet", "true");
				query.setStart(0);
				query.setRows(500);
				query.setQuery(queryStrings);
				query.add(params);
				response = server.query(query);
			}
			catch(Exception e){
				e.printStackTrace();
			}	
		}	
		/* create ImgResult {originalQuery, collated, List<String> imgUrls} */
		return createImgResult(response);
	}
}